package cn.zwx.distributed.svc.service.impl;

import cn.zwx.distributed.svc.domain.entity.WorkerNodeEntity;
import cn.zwx.distributed.svc.domain.enums.WorkerNodeTypeEnum;
import cn.zwx.distributed.svc.mapper.WorkerNodeMapper;
import cn.zwx.distributed.svc.service.WorkerIdService;
import cn.zwx.distributed.svc.utils.DockerUtils;
import cn.zwx.distributed.svc.utils.NetUtils;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @author zhangwenxue
 */
@Service
public class WorkerIdServiceImpl implements WorkerIdService {

    private static final Logger logger = LoggerFactory.getLogger(WorkerIdServiceImpl.class);

    @Resource
    private WorkerNodeMapper workerNodeMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long assignWorkerId() {
        // build worker node entity
        WorkerNodeEntity workerNodeEntity = this.buildWorkerNode();
        // add worker node for new (ignore the same IP + PORT)
        workerNodeMapper.insertSelective(workerNodeEntity);
        logger.info("Add worker node:" + workerNodeEntity);
        return workerNodeEntity.getId();
    }

    private WorkerNodeEntity buildWorkerNode() {
        WorkerNodeEntity workerNodeEntity = new WorkerNodeEntity();
        if (DockerUtils.isDocker()) {
            workerNodeEntity.setType(WorkerNodeTypeEnum.CONTAINER.value());
            workerNodeEntity.setHostName(DockerUtils.getDockerHost());
            workerNodeEntity.setPort(DockerUtils.getDockerPort());

        } else {
            workerNodeEntity.setType(WorkerNodeTypeEnum.ACTUAL.value());
            workerNodeEntity.setHostName(NetUtils.getLocalAddress());
            workerNodeEntity.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt(0,100000));
        }

        return workerNodeEntity;
    }
}
